package com.cirkana.viewer.data.security;

import java.util.Hashtable;

import android.app.Activity;
import android.content.Context;
import android.test.ActivityInstrumentationTestCase2;

import com.cirkana.TestUtils;
import com.cirkana.config.CirkanaConfigException;
import com.cirkana.data.DataException;
import com.cirkana.data.DataNotFoundException;
import com.cirkana.data.security.IUser;
import com.cirkana.data.security.IUserService;
import com.cirkana.viewer.data.ActivityTest;
import com.cirkana.viewer.data.LocalDataConfig;
import com.cirkana.viewer.data.LocalDataProvider;
import com.cirkana.viewer.data.R;

public class SecurityDataResolverTest extends ActivityInstrumentationTestCase2<ActivityTest> {

	private Activity activity;
	private LocalDataConfig localDataConfig;
	private LocalDataProvider localDataProvider;
	private SecurityDataResolver securityDataResolver;

	public SecurityDataResolverTest() {
		super("com.cirkana.viewer.data", ActivityTest.class);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.activity = this.getActivity();
		this.localDataConfig = getLocalDataConfig(this.activity);
		this.localDataProvider = new LocalDataProvider(this.activity, this.localDataConfig);
		this.securityDataResolver = new SecurityDataResolver(this.localDataProvider);
	}

	private LocalDataConfig getLocalDataConfig(Context c) throws CirkanaConfigException {
		return new LocalDataConfig(c.getResources().openRawResource(R.raw.localdata));
	}

	public void testNewUserNull() {
		IUser user = this.securityDataResolver.newUser();
		assertNotNull(user);
		assertNull(user.getId());
		assertNull(user.getNickName());
		assertNull(user.getPassword());
		assertNull(user.getName());
		assertNull(user.getMiddleName());
		assertNull(user.getLastName());
		assertNull(user.getEmail());
		assertNull(user.getBirthDate());
		assertNull(user.getCity());
		assertNull(user.getCountry());
		assertNull(user.getLanguage());
		assertNull(user.getAvatarSummary());
		assertNull(user.getAvatarPicId());
	}

	public void testNewUserEmpty() {
		IUser user = this.securityDataResolver.newUser("", "", "", "", "", TestUtils.testDatePast, "", "", "", 0, "", new Hashtable<String, IUserService>());
		assertNotNull(user);
		assertNull(user.getId());
		assertEquals("", user.getNickName());
		assertNull(user.getPassword());
		assertEquals("", user.getName());
		assertEquals("", user.getMiddleName());
		assertEquals("", user.getLastName());
		assertEquals("", user.getEmail());
		assertEquals(TestUtils.testDatePast, user.getBirthDate());
		assertEquals("", user.getCity());
		assertEquals("", user.getCountry());
		assertEquals("", user.getLanguage());
		assertEquals("", user.getAvatarSummary());
		assertEquals(new Integer(0), user.getAvatarPicId());
	}

	public void testInsertUser() throws DataException {
		testInsertUser(UserTest.testUserEmpty);
		testInsertUser(UserTest.testUser1);
		testInsertUser(UserTest.testUser2);
	}

	private void testInsertUser(User user) throws DataException {
		User inserted = (User) this.securityDataResolver.insertUser(user);
		assertNotNull(inserted);
		assertNotNull(inserted.getId());
		assertEquals(inserted.toText(), user.toText());
	}

	public void testGetUser() throws DataException {
		testGetUser(UserTest.testUser1);
		testGetUser(UserTest.testUser2);
	}

	private void testGetUser(User user) throws DataException {
		this.securityDataResolver.insertUser(user);
		User result = (User) this.securityDataResolver.getUser(user.getNickName(), user.getPassword());
		assertNotNull(result);
		assertEquals(result.toText(), user.toText());
	}

	public void testUpdateUser1() throws DataException {
		testUpdateUser(UserTest.testUser1, UserTest.testUser2);
	}

	public void testUpdateUser2() throws DataException {
		testUpdateUser(UserTest.testUser2, UserTest.testUser1);
	}

	private void testUpdateUser(User initial, User modified) throws DataException {
		this.securityDataResolver.insertUser(initial);
		initial.setNickName(modified.getNickName());
		initial.setPassword(modified.getPassword());
		initial.setName(modified.getName());
		initial.setMiddleName(modified.getMiddleName());
		initial.setLastName(modified.getLastName());
		initial.setEmail(modified.getEmail());
		initial.setBirthDate(modified.getBirthDate());
		initial.setCity(modified.getCity());
		initial.setCountry(modified.getCountry());
		initial.setLanguage(modified.getLanguage());
		initial.setAvatarSummary(modified.getAvatarSummary());
		initial.setAvatarPicId(modified.getAvatarPicId());
		initial.setUserServices(modified.getUserServices());
		this.securityDataResolver.updateUser(initial);
		User result = (User) this.securityDataResolver.getUser(modified.getNickName(), modified.getPassword());
		modified.setId(initial.getId());
		assertEquals(result.toText(), modified.toText());
	}

	public void testDeleteUser() throws DataException {
		testDeleteUser(UserTest.testUser1);
		testDeleteUser(UserTest.testUser2);
	}

	private void testDeleteUser(User user) throws DataException {
		this.securityDataResolver.insertUser(user);
		this.securityDataResolver.getUser(user.getNickName(), user.getPassword());
		this.securityDataResolver.deleteUser(user);
		try {
			this.securityDataResolver.getUser(user.getNickName(), user.getPassword());
			fail("'DataNotFoundException' should be thrown");
		} catch (DataNotFoundException e) {
			assertNotNull(e);
		} catch (DataException e) {
			throw e;
		}
	}
}
